﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing;
using SGP;
using System.IO;
using System.Xml.Linq;



namespace ParticleEditor
{
    public partial class Form1 : Form
    {
        public float PI = 3.14159f;

        public struct Properties
        {
            public string textureFile;
            public int textureID;
            public string name;

            public int emitPosX;
            public int emitPosY;
            public int eType;
            public int emitSizeX;
            public int emitSizeY;
            public float emitRadius;
            public bool looping;
            public float emissionRate;
            public int maxParticles;
            public float emitDirX;
            public float emitDirY;
            public float minDir;
            public float maxDir;
            public float minLife;
            public float maxLife;
            public float minSpeed;
            public float maxSpeed;
            public float minScaleX;
            public float minScaleY;
            public float maxScaleX;
            public float maxScaleY;
            public float rotationRate;
            public Color startColor;
            public Color finColor;
            public int startAlpha;
            public int finAlpha;
        }

        public struct Particle
        {
            public float        currPosX;
            public float        currPosY;
            public float        currLife;
            public float        currSpeed;
            public float        currScaleX;
            public float        currScaleY;
            public float        currRotation;
            public Color        currColor;
            public bool         isAlive;
       
            public float        partDir;	
            public float        currAlpha;
            public float        currRed;
            public float        currGreen;
            public float        currBlue;
            public float        dSpeed; //Change in speed of particle
            public float        dScaleX; //change in scale
            public float        dScaleY;
            public float        dAlpha; //change in Alpha Value
            public float        dRed; //change in Red Value
            public float        dGreen; //change in Green Value
            public float        dBlue; //change in Blue Value
        }

        DateTime currTime = DateTime.Now;
        float timeSince = 0;
        public bool looping = true;
        public Properties prop = new Properties();
        public List<Particle> particles = new List<Particle>();
        public CSGP_TextureManager TM = CSGP_TextureManager.GetInstance();
        public CSGP_Direct3D D3 = CSGP_Direct3D.GetInstance();
       

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);

            if (e.CloseReason == CloseReason.WindowsShutDown) return;

            
            // Confirm user wants to close
            switch (MessageBox.Show(this, "Are you sure you want to quit?", "Quit", MessageBoxButtons.YesNo))
            {
                case DialogResult.No:
                    e.Cancel = true;
                    break;
                default:
                    looping = false;
                    break;
            }
        }

        public void Init()
        {
            Text = "Lofoz's Amazing Particle Editor!";
            prop.name = "BFly";
            tbName.Text = prop.name;
            prop.textureFile = "BFly.png";
            prop.emitPosX = panPreview.Width / 2;
            prop.emitPosY = panPreview.Height / 2;
            prop.eType = 0;
            cbType.SelectedIndex = 0;
            prop.emitSizeX = 0;
            prop.emitSizeY = 0;
            labelEmitScale.Enabled = false;
            labelEmitScaleX.Enabled = false;
            labelEmitScaleY.Enabled = false;
            nudEmitScaleX.Enabled = false;
            nudEmitScaleY.Enabled = false;
            prop.looping = true;
            checkLooping.Checked = true;
            prop.emissionRate = 25;
            nudEmissionRate.Value = 25;
            prop.maxParticles = 100;
            nudMaxParticles.Value = 100;
            prop.emitDirX = 0;
            nudEmitDirX.Value = 0;
            prop.emitDirY = 1;
            nudEmitDirY.Value = 1;
            prop.minDir = -(3.14159f);
            nudMinDir.Value = -180;
            prop.maxDir = 3.14159f;
            nudMaxDir.Value = 180;
            prop.minLife = 1;
            nudMinLife.Value = 1;
            prop.maxLife = 3;
            nudMaxLife.Value = 3;
            prop.minSpeed = 10;
            nudMinSpeed.Value = 10;
            prop.maxSpeed = 50;
            nudMaxSpeed.Value = 50;
            prop.minScaleX = 1;
            nudMinScaleX.Value = 1;
            prop.minScaleY = 1;
            nudMinScaleY.Value = 1;
            prop.maxScaleX = 2;
            nudMaxScaleX.Value = 2;
            prop.maxScaleY = 2;
            nudMaxScaleY.Value = 2;
            prop.rotationRate = 3.14159f / 2;
            nudRotationRate.Value = 90;
            prop.startAlpha = 255;
            nudStartAlpha.Value = 255;
            prop.finAlpha = 25;
            nudFinAlpha.Value = 25;
            prop.startColor = Color.Red;
            butStartColor.BackColor = Color.Red;
            prop.finColor = Color.Blue;
            butFinColor.BackColor = Color.Blue;

            D3.Initialize(panPreview, false);
            TM.Initialize(D3.Device, D3.Sprite);

            prop.textureID = TM.LoadTexture(Directory.GetCurrentDirectory() + "\\..\\..\\TacWars\\resource\\Particles\\" + prop.textureFile);
        }

        public new void Update()
        {
            TimeSpan span = DateTime.Now - currTime;
            currTime = DateTime.Now;
            float dt = (float)span.TotalSeconds;

            timeSince += dt;

            for (int i = 0; i < particles.Count; i++)
            {
                Particle tPart = particles[i];
                if ((tPart.currLife -= dt) <= 0)
                {
                    tPart.isAlive = false;
                    particles[i] = tPart;
                    continue;
                }
                else
                {
                    //Scale Changing
                    tPart.currScaleX += tPart.dScaleX * dt;
                    tPart.currScaleY += tPart.dScaleY * dt;
                    //Vector math for changing speed, and moving particle
                    tPart.currSpeed += tPart.dSpeed * dt;
                    float tempDirX = prop.emitDirX * tPart.currSpeed;
                    float tempDirY = prop.emitDirY * tPart.currSpeed;
                    Vector2DRotate(ref tempDirX, ref tempDirY, tPart.partDir);
                    tPart.currPosX += (tempDirX * dt);
                    tPart.currPosY += (tempDirY * dt);
                    //tPart.currPosX -= ((CSGP_TextureManager.GetInstance().GetTextureWidth(prop.textureID)/2 )*tPart.dScaleX);
                    //tPart.currPosY -= ((CSGP_TextureManager.GetInstance().GetTextureHeight(prop.textureID) / 2) * tPart.dScaleY);
                    
                    //Rotation
                    tPart.currRotation += prop.rotationRate * dt;

                    //Color Blend
                    tPart.currAlpha = tPart.currAlpha + tPart.dAlpha * dt;
                    tPart.currRed = tPart.currRed + tPart.dRed * dt;
                    tPart.currGreen = tPart.currGreen + tPart.dGreen * dt;
                    tPart.currBlue = tPart.currBlue + tPart.dBlue * dt;
                    tPart.currColor = Color.FromArgb(
                        (int)(tPart.currAlpha),
                        (int)(tPart.currRed),
                        (int)(tPart.currGreen),
                        (int)(tPart.currBlue));

                    particles[i] = tPart;
                }
            }

            if (particles.Count < prop.maxParticles)
            {
                if (timeSince > (1 / prop.emissionRate))
                {
                    for (int i = 0; i < timeSince / (1 / prop.emissionRate); i++)
                    {

                        Particle add = new Particle();
                        add.isAlive = true;
                        Random random = new Random();
                        add.currLife = (float)(random.NextDouble() * (prop.maxLife - prop.minLife)) + prop.minLife;
                        //Based on EmitterType
                        switch (prop.eType)
                        {
                            case 0: //Point
                                add.currPosX = prop.emitPosX;
                                add.currPosY = prop.emitPosY;
                                break;
                            case 1: //Rectangle
                                add.currPosX = random.Next((prop.emitPosX + prop.emitSizeX) - prop.emitPosX) + prop.emitPosX;
                                add.currPosY = random.Next((prop.emitPosY + prop.emitSizeY) - prop.emitPosY) + prop.emitPosY;
                                break;
                            case 2: //Circle
                                {
                                    int emitCenX = prop.emitPosX + (int)prop.emitRadius;
                                    int emitCenY = prop.emitPosY + (int)prop.emitRadius;
                                    float newX, newY;
                                    newX = 0;
                                    newY = random.Next((int)prop.emitRadius);
                                    Vector2DRotate(ref newX, ref newY, (float)(random.NextDouble() * (PI * 2)));
                                    add.currPosX = emitCenX + newX;
                                    add.currPosY = emitCenY + newY;
                                    break;
                                }
                            case 3: //Line
                                add.currPosX = random.Next((prop.emitPosX + prop.emitSizeX) - prop.emitPosX) + prop.emitPosX;
                                add.currPosY = prop.emitPosY;
                                break;
                        }
                        ///////////////////////
                        add.currScaleX = prop.minScaleX;
                        add.currScaleY = prop.minScaleY;
                        add.dScaleX = (prop.maxScaleX - prop.minScaleX) / add.currLife;
                        add.dScaleY = (prop.maxScaleY - prop.minScaleY) / add.currLife;
                        add.dSpeed = (prop.maxSpeed - prop.minSpeed) / add.currLife;
                        add.currSpeed = prop.minSpeed;
                        add.partDir = (float)(random.NextDouble() * (prop.maxDir - prop.minDir)) + prop.minDir;
                        add.currRotation = 0f;

                        add.currColor = prop.startColor;
                        add.dAlpha = (prop.finAlpha - prop.startAlpha) / add.currLife;
                        add.dRed = (prop.finColor.R - prop.startColor.R) / add.currLife;
                        add.dGreen = (prop.finColor.G - prop.startColor.G) / add.currLife;
                        add.dBlue = (prop.finColor.B - prop.startColor.B) / add.currLife;

                        add.currAlpha = prop.startAlpha;
                        add.currRed = prop.startColor.R;
                        add.currGreen = prop.startColor.G;
                        add.currBlue = prop.startColor.B;

                        particles.Add(add);
                        timeSince = 0;

                    }
                }
            }

            else if (prop.looping)
            {
                if (timeSince > (1 / prop.emissionRate))
                {
                    for (int j = 0; j < prop.maxParticles; j++)
                    {
                        for (int i = 0; i < timeSince / (1 / prop.emissionRate); i++)
                        {
                            if (!particles[j].isAlive)
                            {
                                Particle add = particles[j];
                                add.isAlive = true;
                                Random random = new Random();
                                add.currLife = (float)(random.NextDouble() * (prop.maxLife - prop.minLife)) + prop.minLife;
                                //Based on EmitterType
                                switch (prop.eType)
                                {
                                    case 0: //Point
                                        add.currPosX = prop.emitPosX;
                                        add.currPosY = prop.emitPosY;
                                        break;
                                    case 1: //Rectangle
                                        add.currPosX = random.Next((prop.emitPosX + prop.emitSizeX) - prop.emitPosX) + prop.emitPosX;
                                        add.currPosY = random.Next((prop.emitPosY + prop.emitSizeY) - prop.emitPosY) + prop.emitPosY;
                                        break;
                                    case 2: //Circle
                                        {
                                            int emitCenX = prop.emitPosX + (int)prop.emitRadius;
                                            int emitCenY = prop.emitPosY + (int)prop.emitRadius;
                                            float newX, newY;
                                            newX = 0;
                                            newY = random.Next((int)prop.emitRadius);
                                            Vector2DRotate(ref newX, ref newY, (float)(random.NextDouble() * (PI * 2)));
                                            add.currPosX = emitCenX + newX;
                                            add.currPosY = emitCenY + newY;
                                            break;
                                        }
                                    case 3: //Line
                                        add.currPosX = random.Next((prop.emitPosX + prop.emitSizeX) - prop.emitPosX) + prop.emitPosX;
                                        add.currPosY = prop.emitPosY;
                                        break;
                                }
                                ///////////////////////
                                add.currScaleX = prop.minScaleX;
                                add.currScaleY = prop.minScaleY;
                                add.dScaleX = (prop.maxScaleX - prop.minScaleX) / add.currLife;
                                add.dScaleY = (prop.maxScaleY - prop.minScaleY) / add.currLife;
                                add.dSpeed = (prop.maxSpeed - prop.minSpeed) / add.currLife;
                                add.currSpeed = prop.minSpeed;
                                add.partDir = (float)(random.NextDouble() * (prop.maxDir - prop.minDir)) + prop.minDir;
                                add.currRotation = 0f;

                                add.currColor = prop.startColor;
                                add.dAlpha = (prop.finAlpha - prop.startAlpha) / add.currLife;
                                add.dRed = (prop.finColor.R - prop.startColor.R) / add.currLife;
                                add.dGreen = (prop.finColor.G - prop.startColor.G) / add.currLife;
                                add.dBlue = (prop.finColor.B - prop.startColor.B) / add.currLife;

                                add.currAlpha = prop.startAlpha;
                                add.currRed = prop.startColor.R;
                                add.currGreen = prop.startColor.G;
                                add.currBlue = prop.startColor.B;

                                particles[j] = add;
                                timeSince = 0;
                                break;
                            }
                        }
                    }
                }

            }
        }

        public void Render()
        {
            D3.Clear(panPreview,Color.Black);
            D3.DeviceBegin();
            D3.SpriteBegin();

            for (int i = 0; i < particles.Count; i++)
            {
                if(particles[i].isAlive)
                    TM.Draw(prop.textureID, (int)particles[i].currPosX - (int)((float)(CSGP_TextureManager.GetInstance().GetTextureHeight(prop.textureID) / 2) * particles[i].currScaleX), 
                        (int)particles[i].currPosY - (int)((float)(CSGP_TextureManager.GetInstance().GetTextureWidth(prop.textureID) / 2) * particles[i].currScaleY), 
                        particles[i].currScaleX, particles[i].currScaleY, Rectangle.Empty, 
                        TM.GetTextureWidth(prop.textureID)/2, TM.GetTextureHeight(prop.textureID)/2, 
                        particles[i].currRotation, particles[i].currColor);
            }

            

            D3.SpriteEnd();
            D3.DeviceEnd();
            D3.Present();
        }

        private void nudEmitScaleX_ValueChanged(object sender, EventArgs e)
        {
            prop.emitSizeX = (int)nudEmitScaleX.Value;
        }

        private void nudEmitScaleY_ValueChanged(object sender, EventArgs e)
        {
            prop.emitSizeY = (int)nudEmitScaleY.Value;
        }

        private void checkLooping_CheckedChanged(object sender, EventArgs e)
        {
            prop.looping = checkLooping.Checked;
        }

        private void nudEmissionRate_ValueChanged(object sender, EventArgs e)
        {
            prop.emissionRate = (float)nudEmissionRate.Value;
        }

        private void nudMaxParticles_ValueChanged(object sender, EventArgs e)
        {
            prop.maxParticles = (int)nudMaxParticles.Value;
        }

        private void nudEmitDirX_ValueChanged(object sender, EventArgs e)
        {
            prop.emitDirX = (float)nudEmitDirX.Value;
        }

        private void nudEmitDirY_ValueChanged(object sender, EventArgs e)
        {
            prop.emitDirY = (float)nudEmitDirY.Value;
        }

        private void nudMinDir_ValueChanged(object sender, EventArgs e)
        {
            prop.minDir = ((float)nudMinDir.Value * PI)/180f;               //DO CONVERSION
        }

        private void nudMaxDir_ValueChanged(object sender, EventArgs e)
        {
            prop.maxDir = ((float)nudMaxDir.Value * PI)/180f;               //DO CONVERSION
        }

        private void nudMinLife_ValueChanged(object sender, EventArgs e)
        {
            prop.minLife = (float)nudMinLife.Value;
        }

        private void nudMaxLife_ValueChanged(object sender, EventArgs e)
        {
            prop.maxLife = (float)nudMaxLife.Value;
        }

        private void nudMinSpeed_ValueChanged(object sender, EventArgs e)
        {
            prop.minSpeed = (float)nudMinSpeed.Value;
        }

        private void nudMaxSpeed_ValueChanged(object sender, EventArgs e)
        {
            prop.maxSpeed = (float)nudMaxSpeed.Value;
        }

        private void nudMinScaleX_ValueChanged(object sender, EventArgs e)
        {
            prop.minScaleX = (float)nudMinScaleX.Value;
        }

        private void nudMinScaleY_ValueChanged(object sender, EventArgs e)
        {
            prop.minScaleY = (float)nudMinScaleY.Value;
        }

        private void nudMaxScaleX_ValueChanged(object sender, EventArgs e)
        {
            prop.maxScaleX = (float)nudMaxScaleX.Value;
        }

        private void nudMaxScaleY_ValueChanged(object sender, EventArgs e)
        {
            prop.maxScaleY = (float)nudMaxScaleY.Value;
        }

        private void nudRotationRate_ValueChanged(object sender, EventArgs e)
        {
            prop.rotationRate = ((float)nudRotationRate.Value * PI)/180f;               //DO CONVERSION
        }

        private void nudStartAlpha_ValueChanged(object sender, EventArgs e)
        {
            prop.startAlpha = (int)nudStartAlpha.Value;
        }

        private void nudFinAlpha_ValueChanged(object sender, EventArgs e)
        {
            prop.finAlpha = (int)nudFinAlpha.Value;
        }

        private void butStartColor_Click(object sender, EventArgs e)
        {
            ColorDialog sColor = new ColorDialog();
            sColor.Color = prop.startColor;

            if (sColor.ShowDialog() == DialogResult.OK)
            {
                prop.startColor = sColor.Color;
                butStartColor.BackColor = prop.startColor;
            }
        }

        private void butFinColor_Click(object sender, EventArgs e)
        {
            ColorDialog fColor = new ColorDialog();
            fColor.Color = prop.finColor;

            if (fColor.ShowDialog() == DialogResult.OK)
            {
                prop.finColor = fColor.Color;
                butFinColor.BackColor = prop.finColor;
            }
        }

        private void cbType_SelectedIndexChanged(object sender, EventArgs e)
        {
            prop.eType = cbType.SelectedIndex;
            //Manipulate tool for type
            switch (prop.eType)
            {
                case 0:
                    panScaleHider.Visible = false;
                    labelEmitScale.Enabled = false;
                    labelEmitScaleX.Enabled = false;
                    labelEmitScaleY.Enabled = false;
                    nudEmitScaleX.Enabled = false;
                    nudEmitScaleY.Enabled = false;
                    break;
                case 1:
                    panScaleHider.Visible = false;
                    labelEmitScale.Enabled =  true;
                    labelEmitScaleX.Enabled = true;
                    labelEmitScaleY.Enabled = true;
                    nudEmitScaleX.Enabled =   true;
                    nudEmitScaleY.Enabled =   true;
                    break;
                case 2:
                    panScaleHider.Visible = true;
                    labelEmitScale.Enabled =  false;
                    labelEmitScaleX.Enabled = false;
                    labelEmitScaleY.Enabled = false;
                    nudEmitScaleX.Enabled =   false;
                    nudEmitScaleY.Enabled =   false;
                    break;
                case 3:
                    panScaleHider.Visible = false;
                    labelEmitScale.Enabled =  true;
                    labelEmitScaleX.Enabled = true;
                    labelEmitScaleY.Enabled = false;
                    nudEmitScaleX.Enabled =   true;
                    nudEmitScaleY.Enabled =   false;
                    break;
            }

        }

        private void Vector2DRotate(ref float fX, ref float fY, float fRadians)
        {
            //	Convert into the Cartesian coordinate system
            fY *= -1.0f;

            float newX, newY;
            newX = ((float)(Math.Cos(fRadians)) * fX) + ((float)(Math.Sin(fRadians)) * fY);
            newY = (-(float)(Math.Sin(fRadians)) * fX) + ((float)(Math.Cos(fRadians)) * fY);

            //	Convert back to our windows coordinate system
            newY *= -1.0f;

            fX = newX;
            fY = newY;
                       
        }

        private void nudRadius_ValueChanged(object sender, EventArgs e)
        {
            prop.emitRadius = (float)nudRadius.Value;
        }

        private void chooseFileToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "All Files|*.*|PNG Files|*.png*|Bitmap Files|*.bmp";
            dlg.FilterIndex = 2;
            dlg.InitialDirectory = Path.GetFullPath(Directory.GetCurrentDirectory() + "\\..\\..\\TacWars\\resource\\Particles");

            if (DialogResult.OK == dlg.ShowDialog())
            {
                TM.UnloadTexture(prop.textureID);
                prop.textureFile = Path.GetFileName(dlg.FileName);
                prop.textureID = TM.LoadTexture(Directory.GetCurrentDirectory() + "\\..\\..\\TacWars\\resource\\Particles\\" + prop.textureFile);
            }

        }

        private void butReset_Click(object sender, EventArgs e)
        {
            particles.Clear();
        }

        private void panPreview_MouseDown(object sender, MouseEventArgs e)
        {
            prop.emitPosX = e.X;
            prop.emitPosY = e.Y;
        }

        private void panPreview_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                prop.emitPosY = e.Y;
                prop.emitPosX = e.X;
            }
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {

            this.Close();
        }

        private void newToolStripMenuItem_Click(object sender, EventArgs e)
        {
            particles.Clear();
            Init();
        }

        private void loadToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog dlg = new OpenFileDialog();
            dlg.Filter = "XML Files|*.xml";
            dlg.FilterIndex = 1;
            dlg.InitialDirectory = Path.GetFullPath(Directory.GetCurrentDirectory() + "\\..\\..\\TacWars\\resource\\Particles");

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                XElement Emitter = XElement.Load(dlg.FileName);
                XElement Name = Emitter.Element("Name");
                prop.name = Name.Value;
                tbName.Text = prop.name;
                XElement Data = Emitter.Element("Data");

                XAttribute IsLooping = Data.Attribute("IsLooping");
                int loop = Convert.ToInt32(IsLooping.Value);
                if (loop == 1)
                    prop.looping = true;
                else
                    prop.looping = false;
                checkLooping.Checked = prop.looping;
                prop.eType = Convert.ToInt32(Data.Attribute("EmitterType").Value);
                cbType.SelectedIndex = prop.eType;
                if (prop.eType == 2)
                    prop.emitRadius = Convert.ToInt32( Data.Attribute("SizeX").Value);
                else
                    prop.emitSizeX = Convert.ToInt32( Data.Attribute("SizeX").Value);
                nudRadius.Value = (decimal)prop.emitRadius;
                nudEmitScaleX.Value = prop.emitSizeX;
                prop.emitSizeY = Convert.ToInt32( Data.Attribute("SizeY").Value);
                nudEmitScaleY.Value = prop.emitSizeY;
                prop.emissionRate = (float)Convert.ToDecimal( Data.Attribute("EmissionRate").Value);
                nudEmissionRate.Value = (decimal)prop.emissionRate;
                prop.maxParticles = Convert.ToInt32( Data.Attribute("MaxParticles").Value);
                nudMaxParticles.Value = prop.maxParticles;

                XElement Part = Emitter.Element("Particle");
                prop.minLife = (float)Convert.ToDecimal( Part.Attribute("MinLife").Value);
                nudMinLife.Value = (decimal)prop.minLife;
                prop.maxLife = (float)Convert.ToDecimal( Part.Attribute("MaxLife").Value);
                nudMaxLife.Value = (decimal)prop.maxLife;
                prop.minSpeed = (float)Convert.ToDecimal( Part.Attribute("MinSpeed").Value);
                nudMinSpeed.Value = (decimal)prop.minSpeed;
                prop.maxSpeed = (float)Convert.ToDecimal( Part.Attribute("MaxSpeed").Value);
                nudMaxSpeed.Value = (decimal)prop.maxSpeed;
                prop.emitDirX = (float)Convert.ToDecimal( Part.Attribute("EmitDirX").Value);
                nudEmitDirX.Value = (decimal)prop.emitDirX;
                prop.emitDirY = (float)Convert.ToDecimal( Part.Attribute("EmitDirY").Value);
                nudEmitDirY.Value = (decimal)prop.emitDirY;
                prop.minDir = (float)Convert.ToDecimal( Part.Attribute("MinDir").Value);
                nudMinDir.Value = (decimal)((prop.minDir*180)/PI);
                prop.maxDir = (float)Convert.ToDecimal( Part.Attribute("MaxDir").Value);
                nudMaxDir.Value = (decimal)((prop.maxDir*180)/PI);
                prop.minScaleX = (float)Convert.ToDecimal( Part.Attribute("MinScaleX").Value);
                nudMinScaleX.Value = (decimal)prop.minScaleX;
                prop.minScaleY = (float)Convert.ToDecimal( Part.Attribute("MinScaleY").Value);
                nudMinScaleY.Value = (decimal)prop.minScaleY;
                prop.maxScaleX = (float)Convert.ToDecimal( Part.Attribute("MaxScaleX").Value);
                nudMaxScaleX.Value = (decimal)prop.maxScaleX;
                prop.maxScaleY = (float)Convert.ToDecimal( Part.Attribute("MaxScaleY").Value);
                nudMaxScaleY.Value = (decimal)prop.maxScaleY;
                prop.rotationRate = (float)Convert.ToDecimal( Part.Attribute("RotationRate").Value);
                nudRotationRate.Value = (decimal)((prop.rotationRate*180)/PI);
                prop.startAlpha = Convert.ToInt32( Part.Attribute("StartA").Value);
                nudStartAlpha.Value = prop.startAlpha;
                int R = Convert.ToInt32( Part.Attribute("StartR").Value);
                int G = Convert.ToInt32( Part.Attribute("StartG").Value);
                int B = Convert.ToInt32( Part.Attribute("StartB").Value);
                prop.startColor = Color.FromArgb(255, R, G, B);
                butStartColor.BackColor = prop.startColor;
                prop.finAlpha = Convert.ToInt32( Part.Attribute("FinA").Value);
                nudFinAlpha.Value = prop.finAlpha;
                R = Convert.ToInt32( Part.Attribute("FinR").Value);
                G = Convert.ToInt32( Part.Attribute("FinG").Value);
                B = Convert.ToInt32( Part.Attribute("FinB").Value);
                prop.finColor = Color.FromArgb(255, R, G, B);
                butFinColor.BackColor = prop.finColor;

                XElement Texture = Part.Element("Texture");
                prop.textureFile = Texture.Value;

                prop.textureID = TM.LoadTexture(Directory.GetCurrentDirectory() + "\\..\\..\\TacWars\\resource\\Particles\\" + prop.textureFile);
            }
        }

        private void saveToolStripMenuItem_Click(object sender, EventArgs e)
        {
            SaveFileDialog dlg = new SaveFileDialog();
            dlg.Filter = "XML Files|*.xml";
            dlg.InitialDirectory = Path.GetFullPath(Directory.GetCurrentDirectory() + "\\..\\..\\TacWars\\resource\\Particles");
            dlg.FilterIndex = 1;
            dlg.FileName = prop.name;

            if (dlg.ShowDialog() == DialogResult.OK)
            {
                XElement Emitter = new XElement("Emitter");
                XElement Name = new XElement("Name", prop.name);
                XElement Data = new XElement("Data");
                int loop = 0;
                if (prop.looping)
                    loop = 1;
                Data.Add(new XAttribute("IsLooping", loop));
                if (prop.eType == 2)
                    Data.Add(new XAttribute("SizeX", prop.emitRadius));
                else
                    Data.Add(new XAttribute("SizeX", prop.emitSizeX));
                Data.Add(new XAttribute("SizeY", prop.emitSizeY));
                Data.Add(new XAttribute("EmissionRate", prop.emissionRate));
                Data.Add(new XAttribute("MaxParticles", prop.maxParticles));
                Data.Add(new XAttribute("EmitterType", prop.eType));

                Emitter.Add(Name);
                Emitter.Add(Data);

                XElement Part = new XElement("Particle");
                Part.Add(new XAttribute("MinLife", prop.minLife));
                Part.Add(new XAttribute("MaxLife", prop.maxLife));
                Part.Add(new XAttribute("MinSpeed", prop.minSpeed));
                Part.Add(new XAttribute("MaxSpeed", prop.maxSpeed));
                Part.Add(new XAttribute("EmitDirX", prop.emitDirX));
                Part.Add(new XAttribute("EmitDirY", prop.emitDirY));
                Part.Add(new XAttribute("MinDir", prop.minDir));
                Part.Add(new XAttribute("MaxDir", prop.maxDir));
                Part.Add(new XAttribute("MinScaleX", prop.minScaleX));
                Part.Add(new XAttribute("MinScaleY", prop.minScaleY));
                Part.Add(new XAttribute("MaxScaleX", prop.maxScaleX));
                Part.Add(new XAttribute("MaxScaleY", prop.maxScaleY));
                Part.Add(new XAttribute("RotationRate", prop.rotationRate));
                Part.Add(new XAttribute("StartA",prop.startAlpha));
                Part.Add(new XAttribute("StartR", prop.startColor.R));
                Part.Add(new XAttribute("StartG", prop.startColor.G));
                Part.Add(new XAttribute("StartB", prop.startColor.B));
                Part.Add(new XAttribute("FinA", prop.finAlpha));
                Part.Add(new XAttribute("FinR", prop.finColor.R));
                Part.Add(new XAttribute("FinG", prop.finColor.G));
                Part.Add(new XAttribute("FinB", prop.finColor.B));                

                XElement Texture = new XElement("Texture", prop.textureFile);
                Part.Add(Texture);
                Emitter.Add(Part);

                Emitter.Save(dlg.FileName);

            }
        }

        private void label2_Click(object sender, EventArgs e)
        {

        }

        private void tbName_TextChanged(object sender, EventArgs e)
        {
            prop.name = tbName.Text;
        }
    }
}
